時間過得好快,不知不覺已經來到第二週了,從這週開始會和大家一起閱讀 DataFusion 的原始碼,
從專案的模組架構逐步理解 DataFusion 在程式碼層面如何從解析查詢語法到實際讀取資料的過程。也相信透過這樣的方式能對 DataFusion 有更深入的理解。
閱讀原始碼之前,我們整個 DataFusion 專案大致的結構,可以看到專案中 datafusion 內有非常多的子目錄,這些子目錄其實都是一個個 crate,也可以說是一個獨立的模組。
......
├── datafusion
│ ├── CHANGELOG.md
│ ├── catalog
│ ├── catalog-listing
│ ├── common
│ ├── common-runtime
│ ├── core
│ ├── datasource
│ ├── datasource-avro
│ ├── datasource-csv
│ ├── datasource-json
│ ├── datasource-parquet
│ ├── doc
│ ├── execution
│ ├── expr
│ ├── expr-common
│ ├── ffi
│ ├── functions
......
DataFusion 主要依照功能拆分這些 Crate,這樣的設計有以下三個優點:
為了能有效的管理多個 Crate,DataFusion 使用 Cargo Workspace 來共享 Crate 間相同的引用,避免重複編譯相同的依賴。
# 專案根目錄的 Cargo.toml
[workspace]
members = [
"datafusion/common",
"datafusion/expr",
"datafusion/sql",
"datafusion/optimizer",
"datafusion/physical-expr",
"datafusion/physical-plan",
"datafusion/core",
# ... 還有更多
]
由於 DataFusion 的 Crate 實在太多了,所以我們今天只介紹幾個和主要功能相關的 Crate
datafusion 主要入口位置:datafusion/core/
作用:對外的統一介面,重新匯出所有核心功能
主要功能:
SessionContext - 查詢的入口關鍵檔案:
src/execution/context.rs - SessionContext 實作src/dataframe/mod.rs - DataFrame APIsrc/prelude.rs - 常用的重新匯出datafusion-common - 共用基礎設施位置:datafusion/common/
作用:提供各模組共用的基礎型別和工具
主要內容:
DataFusionError 型別ScalarValue、Column、DFSchema
為什麼需要 common?
多個 crate 都需要相同的基礎型別,放在 common 避免循環依賴。
datafusion-expr - 邏輯表達式和計劃位置:datafusion/expr/
作用:定義查詢的邏輯表示(與執行無關)
關鍵特性:
datafusion-sql - SQL 解析器位置:datafusion/sql/
作用:將 SQL 字串轉換成 LogicalPlan
工作流程:
SQL 字串
↓
DFParser (基於 sqlparser-rs)
↓
AST (抽象語法樹)
↓
SqlToRel
↓
LogicalPlan
datafusion-optimizer - 查詢優化器位置:datafusion/optimizer/
作用:優化 LogicalPlan,提升查詢性能
datafusion-physical-expr - 物理表達式位置:datafusion/physical-expr/
作用:可執行的表達式實作,直接操作 Arrow 資料
與 datafusion-expr 的差異:
| 特性 | datafusion-expr::Expr |
datafusion-physical-expr::PhysicalExpr |
|---|---|---|
| 目的 | 描述邏輯 | 實際執行 |
| 資料 | 不涉及資料 | 操作 Arrow Arrays |
| 型別 | Schema-aware | 需要具體型別 |
| 優化 | 可被優化器重寫 | 針對執行優化 |
datafusion-physical-plan - 物理執行計劃位置:datafusion/physical-plan/
作用:定義和實作可執行的查詢計劃
理解各個 Crate 之間的依賴關係很重要:
┌─────────────────┐
│ datafusion │ ← 使用者入口
│ (core) │
└────────┬────────┘
│
┌────────────────────┼────────────────────┐
↓ ↓ ↓
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ datafusion- │ │ datafusion- │ │ datafusion- │
│ optimizer │ │ sql │ │ physical- │
│ │ │ │ │ plan │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ ┌──────┴───────┐ │
│ ↓ ↓ │
│ ┌────────────┐ ┌─────────────┐ │
└─────→│ datafusion-│ │ datafusion- │←─ ┘
│ expr │ │ physical- │
│ │ │ expr │
└─────┬──────┘ └──────┬──────┘
│ │
└───────┬───────┘
↓
┌──────────────┐
│ datafusion- │ ← 共用基礎
│ common │
└──────────────┘
依賴層級說明:
datafusion-common:所有其他 crate 的基礎datafusion-expr:定義邏輯表示datafusion-sql, datafusion-optimizer:處理輸入和優化datafusion-physical-expr, datafusion-physical-plan:實際執行datafusion:組合所有功能